#include "stm32f10x.h"                  // Device header
#include "CountSensor.h"
#include "OLED.h"
uint32_t count = 0;
/**
* @brief  进行中断初始化
	* @param  RCC_APB2Periph: 哪一片GPIO（与下面一个参数相对应）
  * @param  GPIOx: 哪一片GPIO（参考GPIO_Init函数）
	* @param  pin：一片GPIO中具体哪个引脚（参照结构体GPIO_InitTypeDef中的定义）
	* @param  mode：此引脚的工作模式（同上）（在官方给出的手册中，GPIO引脚作为外部中断输入端口时应调为浮空、上拉或下拉模式）
	* @param  GPIO_PortSource：与GPIOx对应（参照GPIO_EXTILineConfig,搜索时范围选为current project）
	* @param  GPIO_PinSource：与pin对应（参照GPIO_EXTILineConfig）
	* @param  line：与pin对应（参照GPIO_EXTILineConfig）
	* @param  exti_mode：触发模式之中断触发或事件触发（参照EXTIMode_TypeDef）
	* @param  trigger：触发模式之上升、下降或双边沿触发（参照EXTITrigger_TypeDef）
	* @param  NVIC_PriorityGroup：分组模式（参照NVIC_PriorityGroupConfig，其实对于一个单片机而言，中断的分组方式应当是唯
	一的，要确保所有可能填写分组方式的该参数都是同一个选项，或者干脆不要把这个函数放进任何模块内，只在主函数里执行一次即可）
	* @param  NVIC_IRQChannel：中断通道（参考IRQn_Type，搜索时将范围扩大到整个工程，搜出来的文件是对于所有stm32型号的，认准第243行的
		F10X_MD里的选项,其中EXTI15_10_IRQn合并了10到15的所有中断通道，可以使用这个）
	* @param  NVIC_IRQChannelPreemptionPriority、IRQChannelSubPriority：分别为抢占优先级和相应优先级，参考NVIC_Priority_Table
  * @retval None
  */
void CountSensor_Init(uint32_t RCC_APB2Periph, GPIO_TypeDef* GPIOx, uint16_t pin, GPIOMode_TypeDef mode, uint8_t 
	GPIO_PortSource, uint8_t GPIO_PinSource, uint32_t line, EXTIMode_TypeDef exti_mode, EXTITrigger_TypeDef trigger, 
	uint32_t NVIC_PriorityGroup, IRQn_Type NVIC_IRQChannel, uint8_t IRQChannelPreemptionPriority, uint8_t IRQChannelSubPriority)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph, ENABLE);//先打开AFIO和输入的GPIO引脚，其余外设时钟默认开启
	GPIO_InitTypeDef GPIO_Initstructure;
	GPIO_Initstructure.GPIO_Mode = mode;
	GPIO_Initstructure.GPIO_Pin = pin;
	GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOx, &GPIO_Initstructure);
	GPIO_EXTILineConfig(GPIO_PortSource, GPIO_PinSource);//这个实际上是在对AFIO进行初始化，尽管前缀是GPIO
	EXTI_InitTypeDef EXTI_InitStruct;//配置外部中断
	EXTI_InitStruct.EXTI_Line = line;
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
	EXTI_InitStruct.EXTI_Mode = exti_mode;
	EXTI_InitStruct.EXTI_Trigger = trigger;
	EXTI_Init(&EXTI_InitStruct);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup);//配置NVIC
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = NVIC_IRQChannel;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = IRQChannelPreemptionPriority;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = IRQChannelSubPriority;
  NVIC_Init(&NVIC_InitStruct);
}

void EXTI15_10_IRQHandler()//start->startup_stm32f10x_md.s文件内第61行起为中断向量表，第78行起以IRQHandler结尾的为外部中断的向量表，按照中断路径选取对
	//应的函数
{
	//本例子中的中断路径包括了10-15，在执行中断之前需要先用标志位判断是否是我们选择的第十四号中断路径引发的中断
	if(EXTI_GetITStatus(EXTI_Line14) == SET)
	{
		OLED_ShowNum(1, 1, count, 3);
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
		{
			count++;//本程序采用下降沿触发模式，在此多加一个判断，防止因为外部干扰而乱动（但似乎进行的也不是很好）
		}
		EXTI_ClearITPendingBit(EXTI_Line14);//中断函数执行完后需要手动受释放标志位，否则单片机会不断相应中断，最终卡死
	}
}
